package cn.spream.common.util;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * HttpClient助手
 * Created with IntelliJ IDEA.
 * User: shaojiaxin
 * Date: 13-8-29
 * Time: 上午10:21
 * To change this template use File | Settings | File Templates.
 */
public class HttpClientHelper {

    private DefaultHttpClient httpClient = new DefaultHttpClient();
    private URI uri = null;
    private HttpParams params = new BasicHttpParams();
    private List<Header> headers = new ArrayList<Header>();
    private List<NameValuePair> querys = new ArrayList<NameValuePair>();
    //查询参数编码
    private static Charset QUERY_CHARSET = Charset.defaultCharset();
    //返回结果
    private HttpResponse httpResponse = null;

    private HttpClientHelper(String url) throws URISyntaxException {
        this.uri = new URI(url);
    }

    /**
     * 构建助手
     *
     * @param url
     * @return
     * @throws URISyntaxException
     */
    public static HttpClientHelper build(String url) throws URISyntaxException {
        return new HttpClientHelper(url);
    }

    /**
     * 添加Cookie信息
     *
     * @param name
     * @param value
     * @return
     */
    public HttpClientHelper addCookie(String name, String value) {
        httpClient.getCookieStore().addCookie(new BasicClientCookie(name, value));
        return this;
    }

    /**
     * 添加header信息
     *
     * @param name
     * @param value
     * @return
     */
    public HttpClientHelper addHeader(String name, String value) {
        headers.add(new BasicHeader(name, value));
        return this;
    }

    /**
     * 添加查询参数
     *
     * @param name
     * @param value
     * @return
     */
    public HttpClientHelper addQuery(String name, String value) {
        querys.add(new BasicNameValuePair(name, value));
        return this;
    }

    /**
     * 设置请求超时时间
     *
     * @param milliseconds
     * @return
     */
    public HttpClientHelper setConnectTimeout(long milliseconds) {
        return addParam(CoreConnectionPNames.CONNECTION_TIMEOUT, milliseconds);
    }

    /**
     * 设置响应超时时间
     *
     * @param milliseconds
     * @return
     */
    public HttpClientHelper setSoTimeout(long milliseconds) {
        return addParam(CoreConnectionPNames.SO_TIMEOUT, milliseconds);
    }

    /**
     * 设置请求查询参数编码
     *
     * @param charset
     * @return
     */
    public HttpClientHelper setQueryCharset(String charset) {
        QUERY_CHARSET = Charset.forName(charset);
        return this;
    }

    /**
     * 使用get请求
     *
     * @return
     * @throws IOException
     */
    public String getOfString() throws IOException, URISyntaxException {
        return new String(get(), getContentCharset());
    }

    /**
     * 使用get请求
     *
     * @return
     * @throws IOException
     */
    public byte[] get() throws IOException, URISyntaxException {
        HttpGet httpGet = new HttpGet(uri);
        buildHeaders(httpGet);
        buildParams(httpGet);
        buildQuerys(httpGet);
        return request(httpGet);
    }

    /**
     * 使用post请求
     *
     * @return
     * @throws IOException
     */
    public String postOfString() throws IOException {
        return new String(post(), getContentCharset());
    }

    /**
     * 使用post请求
     *
     * @return
     * @throws IOException
     */
    public byte[] post() throws IOException {
        HttpPost httpPost = new HttpPost(uri);
        buildHeaders(httpPost);
        buildParams(httpPost);
        buildQuerys(httpPost);
        return request(httpPost);
    }

    /**
     * 构建HttpParams
     *
     * @param httpUriRequest
     */
    private void buildParams(final HttpUriRequest httpUriRequest) {
        httpUriRequest.setParams(params);
    }

    /**
     * 构建查询参数
     *
     * @param httpGet
     */
    private void buildQuerys(final HttpGet httpGet) throws IOException, URISyntaxException {
        String query = EntityUtils.toString(new UrlEncodedFormEntity(querys, QUERY_CHARSET));
        httpGet.setURI(new URI(httpGet.getURI().toString() + "?" + query));
    }

    /**
     * 构建查询参数
     *
     * @param httpPost
     * @throws UnsupportedEncodingException
     */
    private void buildQuerys(final HttpPost httpPost) throws UnsupportedEncodingException {
        httpPost.setEntity(new UrlEncodedFormEntity(querys, QUERY_CHARSET));
    }

    /**
     * 添加头信息
     *
     * @param httpUriRequest
     */
    private void buildHeaders(final HttpUriRequest httpUriRequest) {
        for (Header header : headers) {
            httpUriRequest.setHeader(header);
        }
    }

    /**
     * 添加配置
     *
     * @param name
     * @param value
     * @return
     */
    private HttpClientHelper addParam(String name, Object value) {
        params.setParameter(name, value);
        return this;
    }

    /**
     * 请求
     *
     * @param httpUriRequest
     * @return
     * @throws IOException
     */
    private byte[] request(final HttpUriRequest httpUriRequest) throws IOException {
        byte[] bytes = null;
        try {
            this.httpResponse = httpClient.execute(httpUriRequest);
            HttpEntity httpEntity = httpResponse.getEntity();
            if (httpEntity != null) {
                bytes = EntityUtils.toByteArray(httpEntity);
            }
        } finally {
            httpClient.getConnectionManager().shutdown();
        }
        return bytes;
    }

    /**
     * 获取response编码
     *
     * @return
     */
    private Charset getContentCharset() {
        Charset charset = null;
        if (httpResponse != null) {
            HttpEntity httpEntity = httpResponse.getEntity();
            ContentType contentType = ContentType.getOrDefault(httpEntity);
            charset = contentType.getCharset();
        }
        return charset;
    }

    /**
     * 获取返回结果
     *
     * @return
     */
    public HttpResponse getHttpResponse() {
        return httpResponse;
    }
}
